<?php

namespace App\Http\Controllers\Frontend\V10\Financial;

use App\Constant\NewFlowEnum;
use App\Events\AuthStepEvent;
use App\Events\NewFlowOrderEvent;
use App\Exceptions\GeneralException;
use App\Facades\MoneyPlatformRequestFacade;
use App\Facades\SamLogFacade;
use App\Http\Controllers\Controller;
use App\Http\Middleware\CheckCanLoan;
use App\Http\Requests\Frontend\V10\Financial\GetLoanInfoBeforeApplyRequest;
use App\Http\Requests\Frontend\V10\Financial\GetLoanStatusRequest;
use App\Http\Requests\Frontend\V10\Financial\LoanRecordRequest;
use App\Http\Requests\Frontend\V10\Financial\loanRequestApplyRequest;
use App\Http\Requests\Frontend\V10\Financial\LoanStoreRequest;
use App\Http\Requests\Frontend\V10\Financial\ResetHandlerRequest;
use App\Library\String\Strings;
use App\Models\AdminBankIcon;
use App\Models\SettingDocument;
use App\Models\SettingLoan;
use App\Models\User;
use App\Models\UserApplyRiskLog;
use App\Models\UserAuthStepEventLog;
use App\Models\UserDeviceInfo;
use App\Models\UserGlobal;
use App\Models\UserInsuranceLogs;
use App\Models\UserLoanRequest;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
class LoanController extends Controller
{
    // 第三方 购买保险路由
    // const APPLY_INSURANCE_URL = 'http://121.196.206.97/insurance/appsvr/life/donate';

    const APPLY_INSURANCE_URL = 'http://api.anxinbx.com/insurance/gift';
    const TYPE_INSURANCE_APPLY_REPEAT = 1;//已经申请过保险
    const TYPE_INSURANCE_IDCARD_NULL = 2; //身份证或用户名为空
    const TYPE_INSURANCE_IDCARD_NOT_FIND = 3; //未查到身份信息
    const TYPE_INSURANCE_PURCHASE_FAILURE = 4; //购买保险失败
    const TYPE_INSURANCE_NET_EXCEPTION = 5; //服务器异常
    const TYPE_INSURANCE_SUCCESS = 6; //购买保险成功

    public function __construct()
    {

         $this->middleware('auth:api');
         $this->middleware(CheckCanLoan::class)->only(['loanRequestApply','store']);
    }

    /**
     * Description:预生成授信数据
     * Author: Sam
     * DateTime: 2019/1/8 15:35
     * @param LoanStoreRequest $request
     * @return mixed
     * @throws Exception
     */
    public function store(LoanStoreRequest $request)
    {
        /**
         * @var $user User
         */
        $user = Auth::user();
        if ($user->loan_able !== true) {
            return failed("请于{$user->loan_able}再次尝试借款");
        }
        
        $params['loan_money'] = $request->get('loan_money') * 100;
        $params['period'] = $request->get('period');
        $params['user_secure_status'] = $request->get('user_secure_status');
        if (empty($params['user_secure_status'])){
            $params['user_secure_status'] = 1;
        }
        $params['user_id'] = $user->id;
        $params['status'] = UserLoanRequest::STATUS_NOT_VALID;
        $params['trans_id'] = Strings::createSerialNumber($user->id);
        $params['current'] = 1;
        $user_ocr = null;
        $loan = UserLoanRequest::where(['user_id' => $user->id, 'current' => UserLoanRequest::CURRENT_NOW])->get();
        DB::beginTransaction();
        try {
            if ($loan) {
                foreach ($loan as $k =>$v){
                    $v->current = UserLoanRequest::CURRENT_BEFORE;
                    $v->save();
                }

            }
            if ($user_ocr = $user->valid) {
                $params['cert_ocr_id'] = $user_ocr->id;
                $params['status'] = 1;
            }

            $new_loan = UserLoanRequest::create($params);
            if ($user_ocr) {
                $log = [
                    'uid' => $user->id,
                    'step_id' => $user_ocr->id,
                    'type' => UserAuthStepEventLog::STEP_OCR,
                    'loan_request_id' => $new_loan->id,
                ];
                event(new AuthStepEvent($log));
                $new_loan->status = UserLoanRequest::STATUS_UN_APPLY;
                $new_loan->save();
            }
            $device_params = $this->extractInputFromRules($request, $request->rules());
            $device_params['user_id'] = $user->id;
            $device_params['loan_request_id'] = $new_loan->id;
            $device_params['ip'] = $request->getClientIp();
            UserDeviceInfo::create($device_params);
            $error = UserLoanRequest::where(['user_id' => $user->id, 'current' => UserLoanRequest::CURRENT_NOW,])->where('id','<>',$new_loan->id)->get();
            if($error->isNotEmpty()){
                SamLogFacade::debug("授信条数异常");

                DB::rollBack();
                throw new GeneralException('预生成授信结果失败');
            }else{
                DB::commit();
            }
        } catch (Exception $exception) {
            SamLogFacade::debug("预生成用户【{$user->id}】预授信记录失败：{$exception->getMessage()}行数：{$exception->getLine()}");
            DB::rollBack();
            throw new GeneralException('预生成授信结果失败');
        }
        return success([]);
    }

    /**
     * Description:授信申请之后的授信数据信息
     * Author: Sam
     * DateTime: 2019/1/12 21:37
     * @param GetLoanStatusRequest $request
     * @return mixed
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getLoanDetail(GetLoanStatusRequest $request)
    {
        /**
         * @var $user User
         */

        $user = $request->user();
        $loan = UserLoanRequest::where(['user_id' => $user->id, 'current' => UserLoanRequest::CURRENT_NOW,])
            ->where('status','>',1)
            ->with('cashCard')
            ->first();
        if(!$loan){
            return failed('数据异常');
        }
        if(!$loan->cashCard){
            return failed('授信数据银行卡信息异常');
        }
        $num = substr($loan->cashCard->card_num, -4, 4);
        $loan_money = $loan->actually_loan_money ?: $loan->loan_money;
        $period = $loan->actually_period ?: $loan->period;
        $logo = AdminBankIcon::where('bank_name', $loan->cashCard->bank_name)
            ->orWhere('bank_name', $loan->cashCard->bank_show_name)
            ->first() ?: AdminBankIcon::where('bank_name', '其他')
            ->first();

        $data = [
            'loan_money' => $loan_money / 100,
            'period' => $period,
            'bank_info' => "{$loan->cashCard->bank_name_show}($num)",
            'bank_id' => $loan->cashCard->id,
            'logo' => $logo->ali_oss_full_url,
            'pay' => null,
            'days' => null,
            'file' => null,
        ];
        if ($loan->status == UserLoanRequest::STATUS_SUCCESS) {
            $loan_info = [
                'applyAmount' => $data['loan_money'],
                'period' => $period,
                'channel' => $loan->channel ?: '',
            ];
            $pay = UserLoanRequest::getCalculate($loan_info);
            $data['pay'] = $pay;
            $data['days'] = UserLoanRequest::getRestDays($loan->credit_time);
            $data['file'] = SettingDocument::getReceipt($loan->channel);
        }
        return success($data);
    }

    /**
     * Description:申请授信
     * Author: Sam
     * DateTime: 2019-03-02 15:46
     * @param loanRequestApplyRequest $request
     * @return mixed
     * @throws GeneralException
     */
    public function loanRequestApply(loanRequestApplyRequest $request)
    {
        /**
         * @var $user User
         */
        $user = Auth::user();
        $params = $this->extractInputFromRules($request, $request->rules());
        $age = $user->age;
        /**
         * 年龄大于35且选择了教育，改成装修。
         */
        if($age>35&&$params['use']=='02'){
            $params['use'] = '04';
        }
        $marry_status = $user->marry_status;
        /**
         * 婚姻状态为已婚且选择了婚庆改成默认消费
         */
        if($marry_status=='1'&&$params['use']=='03'){
            $params['use'] = '08';
        }
        $loan = UserLoanRequest::where(['user_id' => $user->id, 'current' => UserLoanRequest::CURRENT_NOW])->orderByDesc('id')->first();
        if(!$loan->checkApplyAble()){
            return failed('授信信息异常');
        }
        DB::beginTransaction();
        try{
            $loan->period = $params['period'];
            $loan->cash_card_choice_id = $params['bank_card_id'];
            $loan->use = $params['use'];
            $loan->apply_time = Carbon::now();
            $loan->risk_status = UserApplyRiskLog::STATUS_PROCESSING;
            $loan->status = UserLoanRequest::STATUS_WAIT_FOR_RISK;
            $loan->save();
            $global_data = ['global_status'=>UserGlobal::STATUS_LOAN_REQUEST];
            UserGlobal::where('uid',$loan->user_id)->update($global_data);
            Log::debug('NewFlowOrderEvent start');
            event(new NewFlowOrderEvent(NewFlowEnum::NewFlowLoanInit, $loan));
            DB::commit();
        }catch(Exception $exception){
            SamLogFacade::debug('用户申请授信失败：'.$exception->getMessage());
            DB::rollBack();
            throw new GeneralException('服务器错误!');
        }

        return success([]);
    }

    /**
     * Description:授信申请之前的授信数据信息
     * Author: Sam
     * DateTime: 2019/1/11 21:20
     * @param GetLoanInfoBeforeApplyRequest $request
     * @return mixed
     */
    public function getLoanInfoBeforeApply(GetLoanInfoBeforeApplyRequest $request)
    {
        $user = $request->user();
        $loan = UserLoanRequest::where(['user_id' => $user->id, 'current' => UserLoanRequest::CURRENT_NOW])
            ->with('cashCard')
            ->first();
        if(empty($loan->cashCard)){
            return failed('数据异常');
        }
        $num = substr($loan->cashCard->card_num, -4, 4);
        $logo = AdminBankIcon::where('bank_name', $loan->cashCard->bank_name)
            ->orWhere('bank_name', $loan->cashCard->bank_show_name)
            ->first() ?: AdminBankIcon::where('bank_name', '其他')
            ->first();
        $period_range = SettingLoan::value('period_range');
        $info = [
            'loan_money' => $loan->loan_money / 100,
            'bank_info' => "{$loan->cashCard->bank_name_show}($num)",
            'bank_logo' => $logo->ali_oss_full_url,
            'bank_id' => $loan->cashCard->id,
            'period' => $loan->period,
            'period_range' => json_decode($period_range, true),
            'rate' => config('common.default_rate'),
            'file' => SettingDocument::getDocumentByType('2'),
        ];
        return success($info);
    }

    /**
     * Description:授信失败或完全超时处理
     * Author: Sam
     * DateTime: 2019/1/13 10:04
     * @param ResetHandlerRequest $request
     * @return mixed
     */
    public function resetHandler(ResetHandlerRequest $request)
    {
        $user = $request->user();
        UserGlobal::where('uid',$user->id)->update(['global_status'=>UserGlobal::STATUS_NOTHING]);
        return success([]);
    }

    /**
     * Description:借款记录
     * Author: Sam
     * DateTime: 2019-03-01 19:09
     * @param LoanRecordRequest $request
     * @return mixed
     */
    public function record(LoanRecordRequest $request)
    {
        $user = Auth::user();
        $page_size = $request->get('page_size',5);
        $list = UserLoanRequest::where('user_id',$user->id)
            ->whereIn('status',UserLoanRequest::$record_status)->orderByDesc('created_at')->paginate($page_size);
        $temp = $list->getCollection();
        $res = UserLoanRequest::makeRecord($temp);
        $list->setCollection(collect($res));
        return success($list);
    }

    /**
     * Description: 申请授信后，判断是否已购买过保险
     * @param Request $request
     * @author liChunlong
     * @date 2019-04-10
     */
    public function loanPurchaseInsurance(Request $request) {
        // $user = Auth::user();
        $user = User::where('id','=',11)->first();
        $user_loan = DB::table('user_loan_requests')
                ->where('user_id','=',$user->id)
                ->where('current','=',1)
                ->orderByDesc('id')
                ->first(); 
        $user_secure_status = $user_loan->user_secure_status;
        $is_open = DB::table('setting_hints')->where('type','=',21)->value('status');//保险接口是否开启,默认为1 是开启,2是关闭
        //是否勾选领取保险
        if($user_secure_status == 2 && $is_open == 1) {   
            //是否已经领取过
            if ($user && $user->has_insurance == 1 ) {
                $insertData = [
                    'user_id' => $user->id,
                    'error_msg' => '已经申请过保险',
                    'type' => self::TYPE_INSURANCE_APPLY_REPEAT,
                    'is_success' => 0,
                    'code' => '999',
                ];
                UserInsuranceLogs::create($insertData);
                \Log::debug('购买保险失败，用户:'.$user->id .'已经申请过保险');
                return success();
            }
            $params['mobile'] = $mobile = $user->phone_num ;
            $user_cert = DB::table('user_cert_ocrs')
                ->select('name','num')
                ->where('user_id','=',$user->id)
                ->orderByDesc('id')
                ->first();
            if(!empty($user_cert)) {
                $params['idNo'] = $idNo = $user_cert->num;
                $params['name'] = $name= $user_cert->name;
                if(empty($idNo) || empty($name)) {
                    $insertData = [
                        'user_id' => $user->id,
                        'error_msg' => '身份证或用户名为空',
                        'type' => self::TYPE_INSURANCE_IDCARD_NULL,
                        'is_success' => 0,
                        'code' => '999',
                    ];
                    UserInsuranceLogs::create($insertData);
                    \Log::debug('购买保险失败，用户:'.$user->id .'身份证或用户名为空');
                    return success([],[],'身份证或用户名为空');
                }
            }else {
                $insertData = [
                    'user_id' => $user->id,
                    'error_msg' => '未查到身份信息',
                    'type' => self::TYPE_INSURANCE_IDCARD_NOT_FIND,
                    'is_success' => 0,
                    'code' => '999',
                ];
                UserInsuranceLogs::create($insertData);
                \Log::debug('购买保险失败，用户:'.$user->id .'未查到身份信息');
                return success([],[],'未查到身份信息');
            }
            $params['customerIp'] =  request()->input('ip','127.0.0.1');
            $params['channel'] = 'XL05';
            //获客方式/贷款平台/收入/职业/贷款类型,
            $loan_type = '勾选赠险';
            // $user_loan = DB::table('user_loan_requests')
            //     ->where('user_id','=',$user->id)
            //     ->orderByDesc('id')
            //     ->first();
                
            // $user_secure_status = $user_loan->user_secure_status;
            // if ($user_secure_status == 1){
            //     return success([]);
            // }     
            $loan_use = '小额消费';
            $loan_salary = '10000以上';
            $loan_position = '职员';
            $loan_plate = '快闪卡贷';
            if ($user_loan) {
               if($user_loan->use == UserLoanRequest::USE_CAR){
                   $loan_use = '车贷';
               }elseif ($user_loan->use == UserLoanRequest::USE_DECORATE){
                   $loan_use = '房贷';
               } elseif ($user_loan->use == UserLoanRequest::USE_CONSUME){
                   $loan_use = '小额消费';
               }else{
                   $loan_use = '小额信用';
               }
            }
            $params['remark'] = $loan_type .'/'.$loan_plate.'/'.$loan_salary.'/'.$loan_position.'/'.$loan_use;
            // dd($params);
            $url = self::APPLY_INSURANCE_URL;

            try{
                $result = $this->send_apply_insurance($url,'POST',$params);
                if (false === $result) {
                    $insertData = [
                        'user_id' => $user->id,
                        'error_msg' => '接口错误',
                        'type' => self::TYPE_INSURANCE_NET_EXCEPTION,
                        'is_success' => 0,
                        'code' => '999',
                    ];
                    UserInsuranceLogs::create($insertData);
                    \Log::debug('购买保险失败，用户：'.$user->id .'失败原因：接口错误');
                    return success([]);
                }
                if($result && $result['ret'] == 200) {
                    // dd($result);    
                    if($result['bizData']['code'] == '000') {
                        $insertData = [
                            'user_id' => $user->id,
                            'error_msg' => '购买保险成功',
                            'type' => self::TYPE_INSURANCE_SUCCESS,
                            'is_success' => 1,
                            'code' => $result['bizData']['code'],
                        ];
                        UserInsuranceLogs::create($insertData);
                        DB::table('users')->where('id',$user->id)->update([
                            'has_insurance'=>1
                        ]);
                    }else {
                        $insertData = [
                            'user_id' => $user->id,
                            'error_msg' => $result['bizData']['errMsg'],
                            'type' => self::TYPE_INSURANCE_PURCHASE_FAILURE,
                            'is_success' => 0,
                            'code' => $result['bizData']['code'],
                        ];
                        UserInsuranceLogs::create($insertData);
                        \Log::debug('购买保险失败，用户：'.$user->id .'失败原因：'.$result['bizData']['errMsg']);
                        return success([]);
                    }
                }else {
                    $insertData = [
                        'user_id' => $user->id,
                        'error_msg' => '服务器异常',
                        'type' => self::TYPE_INSURANCE_NET_EXCEPTION,
                        'is_success' => 0,
                        'code' => '999',
                    ];
                    UserInsuranceLogs::create($insertData);
                    \Log::debug('购买保险失败，用户：'.$user->id .'失败原因:服务器异常');
                    return success([],[],'服务器异常');
                }
            }catch (\Exception $exception) {
                $insertData = [
                    'user_id' => $user->id,
                    'error_msg' => '服务器异常',
                    'type' => self::TYPE_INSURANCE_NET_EXCEPTION,
                    'is_success' => 0,
                    'code' => '999',
                ];
                UserInsuranceLogs::create($insertData);
                \Log::debug('购买保险失败，用户：'.$user->id .'异常原因：'.$exception->getMessage());
                return success([],[],$exception->getMessage());
            }
            return success([]);
        }
    }

    /**
     * @Author liChunlong
     * @date 2019-04-10
     * Description: 调取保险接口
     * @param string $url
     * @param string $method
     * @param $params
     * @return mixed
     */
    private function send_apply_insurance($url='',$method='POST',$params) {
        $http_url = $url;
        $client = new Client();
        try {
            $response = $client->request($method, $http_url, [
                'form_params' => $params,
                'headers' => [
                    'User-Agent' => $_SERVER['HTTP_USER_AGENT'],
                    'Content-Type' => 'application/x-www-form-urlencoded',
                ],
                'timeout' => 5
            ]);
        } catch (\Exception $e) {
            return false;
        }
        if(array_key_exists('code',$response) && $response['code']!=200) {
            return false;
        }
        $ret = json_decode($response->getBody()->getContents(), true);

        if(!array_key_exists('bizData',$ret) && $ret['ret']!=200) {
            return false;
        }
        return  $ret;
    }


}
